package com.myacg.core.dao.base;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.myacg.core.dao.service.RecordService;
import com.myacg.editor.common.utils.SystemUtils;

 

public class EntityTableJsonDB{
	 private static  EntityTableJsonDB entityTableJsonDB;
	 private Map<String,EntityTable> entityTableMap   ;
	 public static EntityTableJsonDB getInstance(){
			 if(entityTableJsonDB ==  null){
				 entityTableJsonDB = new EntityTableJsonDB();
			 }
		 return entityTableJsonDB;
	 }
	 private RecordService<EntityTable> dbservice;
	 public static final String entityTableDbPath = "com/myacg/core/dao/base/EntityTable";
	 private  EntityTableJsonDB(){ 
		  dbservice = new RecordService<>(EntityTable.class,getRealDBPath(EntityTableJsonDB.entityTableDbPath) );
		  //加载文件内容到缓存中
		  initTablesMap();
	 }
	 /**
	  * 将json文件中加入到entityTableMap的缓存中
	  * 可以根据class获取对应的entityTable
	  */
	 private void initTablesMap(){
		 	this.entityTableMap = new HashMap<>();
		    List<EntityTable> tableList = this.dbservice.getAllRecords();
		    for (EntityTable entityTable : tableList) {
		    	entityTableMap.put(entityTable.getClassPath(), entityTable);
			}
	 }
	 
	 /**
	  * 扫描将指定文件夹下(包)的内容写入到dbTable的文件中
	  * @param projectEntityPaths
	  * @throws Exception
	  */
	 public  void reBuildDBTables(String[] projectEntityPaths) throws Exception{
		   //如果 entityTable没有对应的
		   Map<String,String> resultFiles= new HashMap<>();
		   for (String projectEntityPath : projectEntityPaths) {
			   //扫描
			   scanFileAndFilePath(new File(projectEntityPath),resultFiles);
		   }
		   //扫描的javabean转换到表中
		   List<EntityTable>   tables =formatEntityTables(resultFiles);
		   //将表内容加入  
		   this.dbservice.deletedAll();
		   this.dbservice.addRecords(tables);
		   //重置缓存
		   this.initTablesMap();
	 }
	  
	 
	/**
	 * 将包下的数据组织到entityTable中
	 * @param resultFiles
	 * @return
	 * @throws ClassNotFoundException 
	 */
	private List<EntityTable>  formatEntityTables(Map<String,String> resultFiles) throws ClassNotFoundException{
		    Set<String> entityPaths = resultFiles.keySet();
		    List<EntityTable>   tables = new ArrayList<>();
		    for (String entityPath : entityPaths) {
		    	String entityName = entityPath.substring(entityPath.lastIndexOf("\\")+1, entityPath.length());
		    	EntityTable entityTable = new EntityTable();
		    	entityTable.setTableName(entityName);
		    	entityTable.setClassPath(resultFiles.get(entityPath));
		    	entityTable.setDbFilePath(entityPath);
		    	//设置字段信息
		    	entityTable.setEntityFiellds(getFileds(entityTable.getClassPath())); 
		    	tables.add(entityTable);
			}
		return tables;
	}
	
	 /**
	  * 封装类对应的字段信息
	  * @param entityClassPath
	  * @return
	  * @throws ClassNotFoundException
	  */
	 private  List<EntityField> getFileds(String  entityClassPath) throws ClassNotFoundException{
		  Class  entityClass = Class.forName(entityClassPath);
		  List<EntityField>  entityFields = new ArrayList<>();
		  Field[] fields = entityClass.getDeclaredFields();
		  for (Field field : fields) {
			  EntityField  entityField =  new EntityField();
			  entityField.setFiledName(field.getName());
			  String type= field.getType().getName();
			  entityField.setFiledTypeClass(type);
			  entityField.setFiledType(type.substring(type.lastIndexOf(".")+1,type.length()));
			  entityFields.add(entityField);
		  }
		 return  entityFields; 
	 }
	
	
	 /**
	  * 将扫描的文件夹下的所有java文件
	  * @param file
	  * @param resultFiles
	  */
	 private void scanFileAndFilePath(File   file,Map<String,String> resultFiles){
		 File[] files = file.listFiles();
	      for (File file2 : files) {
	    	   if(file2.isDirectory()){
	    		   //文件夹 继续深入
	    		   scanFileAndFilePath(file2,resultFiles);
	    	   }else{
	    		   if(file2.isFile()){
	    			   //找到文件后
	    			   String  javaFilePath = file2.getPath();
	    			   System.err.println("scan entity File: "+javaFilePath);
	    			   resultFiles.put(this.getbasePath(javaFilePath), this.getClassPath(javaFilePath));
	    		   }
	    	   }
	      }
	 }
	
	 
	 /**
	  * 获取类路径
	  * @param javaFilePath
	  */
	 private String  getClassPath(String javaFilePath){
		  return getbasePath(javaFilePath).replace("\\", ".");
	 }
	 
	 /**
	  * 获取相对文件路径
	  */
	 private String   getbasePath(String javaFilePath){
		 String basePath = SystemUtils.getProjectSrcPath();
		 return  javaFilePath.substring(basePath.length() , javaFilePath.length()).replace(".java", "");
	 }
	 
	 /**
	  * 获取存储db的路径
	  * @param entityTable
	  * @return
	  */
	 public String getRealDBPath(String  dbFilePath){ 
		 return  SystemUtils.getProjectDBPath()+ dbFilePath+"\\";
	 }
	 
	 
	 public EntityTable getEntityTable(Class entityClass){
		 //以类名为键获取加载的EntityTable
		return this.entityTableMap.get(entityClass.getName());
	 }
	 
//	 public  void createDBfile(EntityTable entityTable){
//		 String dirpath = this.getRealDBPath(entityTable.getDbFilePath());
//		 String indexfilePath = this.getRealDBPath(entityTable.getDbFilePath())+"index.bak";
//			if(indexfilePath!=null){
//				   File dir =new File(dirpath);
//				   File file =new File(indexfilePath);
//				   if(!file.exists()){
//				    try {
//				    	System.err.println("created file sucess:"+indexfilePath);
//						 dir.mkdirs();
//						file.createNewFile();
//						 
//					} catch (IOException e) {
//						System.err.println(indexfilePath+"  create err  : "+e.getMessage());
//					}
//				  }
//		    }
//	 }
	 
	 public RecordService<EntityTable> getDbservice() {
		return dbservice;
	}
 
}
